
package SemanticoPacote;

import SemanticoPacote.TratamentoErroSemantico.ErroSemantico;
import SintaticoPacote.*;
import compilador_full.TabelaSimbolos;
import java.util.Hashtable;

/**
 *
 * @author Wilson
 */

/*********************************************************************** /
    <declaracaoMetodoVoid> ::= void <nome> ( (<parametros>|E) ){<cmd>}
/************************************************************************/

public class declaracaoMetodosVoid {

    private Hashtable<Integer, String> metodos = new Hashtable<Integer, String>();
    String escopo = null;

    public void declaraMetodosVoid(TabelaSimbolos tabelaSimbolos, int indice){

        declaracaoStructs verificaDeclaracaoStruct = new declaracaoStructs();
        declaracaoVariaveis verificaDeclaracaoVariaveis = new declaracaoVariaveis(tabelaSimbolos);
        cmd verificaCmd = new cmd();
        chamadaDeFuncao verificaChamadaDeFuncao = new chamadaDeFuncao(tabelaSimbolos);

        tabelaSimbolos.soConsome(); //consome void


        //pergunta se já existe um metodo com esse nome
        if(this.jaContemAqueleMetodoVoid(tabelaSimbolos.getLookahead(),indice))
            if(!tabelaSimbolos.verificaDuplicidadeDeMetodo(tabelaSimbolos.getLookahead())){
                System.out.println("ERRO SEMANTICO - " + tabelaSimbolos.getLookahead() + " na linha " + tabelaSimbolos.getLinha() + " metodo ja declarado");
                ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: O método já foi declarado");
            }
        String nomeMetodo = tabelaSimbolos.getLookahead();

        escopo = tabelaSimbolos.getLookahead();
        tabelaSimbolos.soConsome(); //consome nome do metodo void
        tabelaSimbolos.soConsome(); //consome o (


        while (!(tabelaSimbolos.getLookahead().equals(")"))) { // consome todos os parâmentros, até achar o )
                       System.out.println("no metodo " + tabelaSimbolos.getLookahead());
                       tabelaSimbolos.soConsome();

                       if(tabelaSimbolos.getLookahead().equals("*")){
                           tabelaSimbolos.soConsome();
                       }
                       System.out.println("no metodo " + tabelaSimbolos.getLookahead());
                       if(tabelaSimbolos.verificaSeFoiDeclaradoComoGlobal(tabelaSimbolos.getLookahead())){
                           System.out.println("ERRO SEMANTICO - " + tabelaSimbolos.getLookahead() + " na linha " + tabelaSimbolos.getLinha() + " variavel do parametro ja declarado");
                               ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada");
                       }
                               

                       tabelaSimbolos.soConsome();

                       System.out.println("no metodo " + tabelaSimbolos.getLookahead());
                       if(tabelaSimbolos.getLookahead().equals(","))
                           tabelaSimbolos.soConsome();
        }

        tabelaSimbolos.soConsome(); // consome o parêntese )
        tabelaSimbolos.soConsome();// Consome o {


        while (tabelaSimbolos.getLookahead().equals("typedef") ||
                tabelaSimbolos.getLookahead().equals("struct") ||
                Tipos.apenasCompara(tabelaSimbolos)) {


            if (tabelaSimbolos.getLookahead().equals("typedef")) {
                if (tabelaSimbolos.superLookahead(1).equals("struct")) {
                  //  int v = analise.getIndiceStruct();
                    verificaDeclaracaoStruct.declaraStructs(tabelaSimbolos);


                } else if (Tipos.apenasCompara(tabelaSimbolos)) {
                    verificaDeclaracaoVariaveis.declaraVariaveis();



                } else if (tabelaSimbolos.getLookahead().equals("struct")) {
                 //   int v1 = analise.getIndiceStruct();
                    verificaDeclaracaoStruct.declaraStructs(tabelaSimbolos);
                }

            } else if (Tipos.apenasCompara(tabelaSimbolos)) {

                if (tabelaSimbolos.superTipo(1).equals("identificador")) {
                    verificaDeclaracaoVariaveis.declaraVariaveis();
                } else if (tabelaSimbolos.superLookahead(1).equals("*")) {
                    verificaDeclaracaoVariaveis.declaraVariaveis();
                }
            }
        }

        while (tabelaSimbolos.getLookahead().equals("*") |
                tabelaSimbolos.getLookahead().equals("printf") |
                tabelaSimbolos.getLookahead().equals("scanf") |
                tabelaSimbolos.getLookahead().equals("do") |
                tabelaSimbolos.getLookahead().equals("while") |
                tabelaSimbolos.getLookahead().equals("for") |
                tabelaSimbolos.getLookahead().equals("if") |
                tabelaSimbolos.getTipo().equals("identificador")) {

            verificaCmd.sintaxeCmd(tabelaSimbolos, escopo);
        }

        tabelaSimbolos.soConsome();//consome }
    }


    public boolean jaContemAqueleMetodoVoid(String metodo, int indice){


        if(!metodos.contains(metodo)){
            metodos.put(indice, metodo);
            return false;// retorna false pq nao tinha
        }
        else
            return true;//ja contém aquela constante

    }

}

